using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Win32;
using System.Windows.Forms;
using System.Drawing;
using Studio.Windows;

namespace Studio.Game.GameBox
{
    /// <summary>
    /// Script Expert, Parse Script
    /// </summary>
    public class AgentScriptParser : AgentScript
    {

        /// <summary>
        /// Local Var List supportted by AgentScript
        /// </summary>
        protected IDictionary<string, string> _VarList;


        public AgentScriptParser()
            : base()
        {
            _VarList = new Dictionary<string, string>();
        }

        /// <summary>
        /// Constructor
        /// </summary>
        public AgentScriptParser(IList<string> Scripts) 
            : base(Scripts) 
        {
            _VarList = new Dictionary<string, string>();
        }
    

        /// <summary>
        /// Set a variable
        /// </summary>
        public void SetAgent(string VarName, string VarValue)
        {
            _VarList.Remove(VarName);
            _VarList.Add(VarName, VarValue);
        }

        /// <summary>
        /// Return the VarValue of specified VarName
        /// </summary>
        public string GetAgent(string VarName)
        { 
            string Value;
            _VarList.TryGetValue(VarName, out Value);
            return Value;
        }

        /// <summary>
        /// Simulate keyboard, send keys to foreground window
        /// </summary>
        public void SendKeys(string Keys)
        {
            // Send message directly to foreground window
            System.Windows.Forms.SendKeys.SendWait(Keys);
        }

        /// <summary>
        /// Simulate Mouse Move
        /// </summary>
        public void MouseMove(int x, int y)
        {
            WinAPI.SetCursorPos(x, y);
        }

        public void MouseMove(Point o) { MouseMove(o.X, o.Y); }

        /// <summary>
        /// Simulate Mouse Click
        /// </summary>
        public void MouseClick()
        {
            WinAPI.mouse_event(Constants.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, (UIntPtr)0);
            WinAPI.mouse_event(Constants.MOUSEEVENTF_LEFTUP, 0, 0, 0, (UIntPtr)0);
        }

        /// <summary>
        /// Mouse move & click
        /// </summary>
        public void MouseClick(int x, int y)
        {
            MouseMove(x, y);
            MouseClick();
        }

        public void MouseClick(Point o) { MouseClick(o.X, o.Y); }
        /// <summary>
        /// Run a sentence. The return value is for GetAgent
        /// </summary>
        public string Run(AgentScriptSentence Sentence)
        {
            switch (Sentence.Keyword)
            {
                case Keywords_V1.COMMENT:
                case Keywords_V1.FORMAT:
                case Keywords_V1.VERSION:
                    // Nothing to do...
                    break;
                case Keywords_V1.GETAGENT:
                    return GetAgent(Sentence.Params[0]);
                case Keywords_V1.SETAGENT:
                    SetAgent(Sentence.Params[0], Sentence.Params[1]);
                    break;
                case Keywords_V1.SENDKEYS:
                    SendKeys(Sentence.Params[0]);
                    return Sentence.Params[0];
                case Keywords_V1.MOUSEMOVE:
                    MouseMove(int.Parse(Sentence.Params[0]), int.Parse(Sentence.Params[1]));
                    break;
                case Keywords_V1.MOUSECLICK:
                    if (2 == Sentence.Params.Length)
                        MouseClick(int.Parse(Sentence.Params[0]), int.Parse(Sentence.Params[1]));
                    else
                        MouseClick();
                    break;
                case Keywords_V1.SLEEP:
                    System.Threading.Thread.Sleep(int.Parse(Sentence.Params[0]));
                    break;
                case Keywords_V1.CALLAGENT:
                    throw new Exception("Unsupported.");
                case Keywords_V1.INVALID:
                default:
                    break;
            }
            return string.Empty;
        }
    }
}
